<?php
declare (strict_types = 1);
namespace app\logic;

use app\model\HandleProject;
use app\model\HandleProjectCases;
use app\model\HandleProjectRow;
use app\model\HandleProjectTask;
use app\logic\RedisLogic;
use think\facade\Db;

class ProjectLogic
{
    protected $rename_callback = 'test_rename_callback';

    public static function ins() {
        static $cls;
        if (!$cls) {
            $cls = new static();
        }
        return $cls;
    }

    /**
     * 添加项目
     * @param string $title
     * @return array
     */
    public function addProject($title)
    {
        $title = trim($title);
        if (empty($title)) {
            return errorMsg('未知项目名称');
        }
        
        $exist = HandleProject::ins()->where('state', 1)
            ->where('title', $title)
            ->value('id');
        if ($exist > 0) {
            return errorMsg('项目名称已存在');
        }
        $project_uuid = getGuid();
        $data = [
            'uuid' => $project_uuid,
            'title' => $title,
            'state' => 1
        ];
        $result = HandleProject::ins()->insertGetId($data);
        if ($result > 0) {
            // $root_dir = FileLogic::ins()->getCleanFileDir();
            $root_dir = FileLogic::ins()->getLocalCleanFileDir();
            $project_dir = $root_dir.DIRECTORY_SEPARATOR.date('Y-m-d').DIRECTORY_SEPARATOR.$title;
            
            $childen_dir = ["1、基础清洗文件","2、资质文件","3、担保-反担保-通知","4、反担保-原告-通知","5、担保-原告-通知","6、债转协议及清单","7、补充文件"];

            foreach($childen_dir as $d){
                if(!is_dir($project_dir.DIRECTORY_SEPARATOR.$d)){
                    mkdir($project_dir.DIRECTORY_SEPARATOR.$d,0777,true);
                }
            }

            $task_data = [
                ['project_uuid'=>$project_uuid,'task_name'=>'文件检索','action_type'=>1,'state'=>0],
                ['project_uuid'=>$project_uuid,'task_name'=>'普通类文件','action_type'=>2,'state'=>0],
                ['project_uuid'=>$project_uuid,'task_name'=>'资质类文件','action_type'=>3,'state'=>0],
                ['project_uuid'=>$project_uuid,'task_name'=>'通知类文件','action_type'=>4,'state'=>0],
                ['project_uuid'=>$project_uuid,'task_name'=>'债转协议清单','action_type'=>5,'state'=>0],
                ['project_uuid'=>$project_uuid,'task_name'=>'补充类文件','action_type'=>6,'state'=>0]
            ];
            $result = HandleProjectTask::ins()->insertAll($task_data);


            return successMsg('操作成功');

        } else {
            return errorMsg('操作失败');
        }
    }

    /**
     * 获取项目列表
     * @return array
     */
    public function getProjectList()
    {
        $list = HandleProject::ins()->where('state', 1)
            ->order('id desc')
            ->paginate(['list_rows'=>10])->toArray();
        foreach($list['data'] as $k=>$row){
            $task = HandleProjectTask::ins()->where('project_uuid',$row['uuid'])->select()->toArray();
            foreach($task as $x=>$v){
                if($v['state'] == 0){
                    $task[$x]['state_txt'] = '--';
                }elseif($v['state'] == 1){
                    $task[$x]['state_txt'] = '执行中';
                }elseif($v['state'] == 3){
                    $task[$x]['state_txt'] = '已执行';
                }
            }
            $list['data'][$k]['task_type'] = $task;

            $list['data'][$k]['excel_status'] = (bool) HandleProjectCases::ins()->where('project_uuid',$row['uuid'])->value('id');
        }
        return $list;
    }

    /**
     * 获取项目信息
     * @param string $uuid
     * @return array|null
     */
    public function getProjectInfo($uuid) {
        if (empty($uuid)) {
            return null;
        }
        $info = HandleProject::ins()->where('state', 1)
            ->where('uuid', $uuid)
            ->findOrEmpty()->toArray();
        if (empty($info)) {
            return null;
        }
        return $info;
    }

    /**
     * 获取文件名修改结构化数据
     */
    private function renameFileData()
    {
        $fileData = Db::name('handle_file_name')->column('new_name','old_name');
        return $fileData;
    }

    /**
     * 保存要素表数据到数据库
     * @param array $fileData 
     * @param string $fhUuid 
     * @return array | bool 
     */
    public function saveExcelData($fileData,$fhUuid)
    {
         foreach ($fileData as $key => $val) {
            if ($key <= 0) continue;
            if($val[0] === null) continue;
            $_val = trim($val[0]);
            if (empty($_val)) continue;
            $caseNos[$_val] = $val;
        }
        if (empty($caseNos)) {
            return errorMsg('未找到案件标识信息');
        }
        
        $insert_data = ['data_content'=>json_encode($caseNos, JSON_UNESCAPED_UNICODE)];
        $id = HandleProjectCases::where(['project_uuid' => $fhUuid])->value('id');
        if($id){
            $result =HandleProjectCases::where(['id' => $id])->update($insert_data);
        }else{
            $insert_data['project_uuid'] = $fhUuid;
            $result = HandleProjectCases::ins()->save($insert_data); // 将要素信息保存到数据库中
        }
        
        if ($result === false) {
            return errorMsg('保存案件要素信息失败');
        }
        HandleProject::ins()->where(['uuid' => $fhUuid])->update(['case_total'=>(count($caseNos))]); // 更新案件总数
        
        return true;
    }

    /**
     * 开始清洗任务   XXXXXXX
     * @param string $fhUuid 
     * @param array $projectInfo 
     * @return array
     */
    public function addChangeFileStream($fhUuid,$projectInfo)
    {
        $fhTitle = $projectInfo['title'];
        $fhDate = substr($projectInfo['create_time'],0,10);
        $caseDetail = HandleProjectCases::where(['project_uuid' => $fhUuid])->value('data_content');
        $caseDetailData = json_decode($caseDetail,true);
        if(json_last_error() !== JSON_ERROR_NONE)
        {
            return errorMsg('要素表数据异常，请重新上传');
        }
        $contracts = array_keys($caseDetailData);
        $bash_path = FileLogic::ins()->getCleanFileDir(3).DIRECTORY_SEPARATOR.$fhDate.DIRECTORY_SEPARATOR.$fhTitle.DIRECTORY_SEPARATOR."1、基础清洗文件";
        $contrast_table = $this->renameFileData();
        foreach($contracts as $jb){
            $type = 'file_change_name_by_table';
            $stream_data['dir_path'] = $bash_path.DIRECTORY_SEPARATOR.$jb;
            $stream_data['contrast_table'] = $contrast_table;
            $stream_result = RedisLogic::ins()->addTaskStream($type,$stream_data,$this->rename_callback);
            $insert_data['task_id'] = $stream_result['data'][1];
            $insert_data['project_uuid'] = $fhUuid;
            $insert_data['case_dir'] = $jb;
            $insert_data['state'] = 0;
            // 写入数据库
            $r = HandleProjectRow::ins()->insert($insert_data);
        }
        HandleProject::ins()->where(['uuid' => $fhUuid])->update(['clean_status'=>1]); // 清洗状态
        return successMsg('数据清洗中...'); 
    }

    /**
     * 再次开始上次失败的清洗任务
     * @param string $fhUuid 
     * @param array $projectInfo 
     * @return array
     */
    public function againChangeFileStream($fhUuid,$projectInfo)
    {
        $fhTitle = $projectInfo['title'];
        $fhDate = substr($projectInfo['create_time'],0,10);
        
        $contracts = HandleProjectRow::ins()->where('project_uuid',$fhUuid)->where('state',3)->column('case_dir');
        $bash_path = FileLogic::ins()->getCleanFileDir(3).DIRECTORY_SEPARATOR.$fhDate.DIRECTORY_SEPARATOR.$fhTitle.DIRECTORY_SEPARATOR."1、基础清洗文件";
        $contrast_table = $this->renameFileData();
        foreach($contracts as $jb){
            $type = 'file_change_name_by_table';
            $stream_data['dir_path'] = $bash_path.DIRECTORY_SEPARATOR.$jb;
            $stream_data['contrast_table'] = $contrast_table;
            $stream_result = RedisLogic::ins()->addTaskStream($type,$stream_data,$this->rename_callback);
            $insert_data['task_id'] = $stream_result['data'][1];
            $insert_data['project_uuid'] = $fhUuid;
            $insert_data['case_dir'] = $jb;
            $insert_data['state'] = 0;
            $r = HandleProjectRow::ins()->where([['project_uuid', '=', $fhUuid],['case_dir', '=', $jb]])->delete();
            // 写入数据库
            $r = HandleProjectRow::ins()->insert($insert_data);
        }
        return successMsg('添加完成，再次数据清洗中...'); 
    }
}